<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>02_深拷贝和浅拷贝-基本使用</title>
  <!-- 
  在JavaScript中，深拷贝和浅拷贝是处理对象和数组时非常重要的概念。它们的使用场景和实现方式各有不同，理解这些概念可以帮助我们更好地管理数据。
  浅拷贝（Shallow Copy）
  定义：浅拷贝是指创建一个新对象，这个新对象的属性是原对象属性的引用。对于基本数据类型（如字符串、数字、布尔值等），会直接复制其值；而对于引用类型（如对象、数组等），则会复制其引用。

   基本使用
  1. 使用  `Object.assign()`  方法：
  const obj1 = { a: 1, b: { c: 2 } };
    const shallowCopy = Object.assign({}, obj1);
    shallowCopy.b.c = 3; // 修改浅拷贝的对象
    console.log(obj1.b.c); // 输出 3，原对象也被修改
  2. 使用扩展运算符（Spread Operator）：
  const obj1 = { a: 1, b: { c: 2 } };
    const shallowCopy = { ...obj1 };
    shallowCopy.b.c = 3; // 修改浅拷贝的对象
    console.log(obj1.b.c); // 输出 3，原对象也被修改
  深拷贝（Deep Copy）

  定义：深拷贝是指创建一个新对象，这个新对象及其所有嵌套对象都是原对象的独立副本。深拷贝会递归地复制对象的所有属性，确保修改新对象不会影响原对象。

   基本使用
  1. 使用  `JSON.parse()`  和  `JSON.stringify()`  方法：
  const obj1 = { a: 1, b: { c: 2 } };
    const deepCopy = JSON.parse(JSON.stringify(obj1));
    deepCopy.b.c = 3; // 修改深拷贝的对象
    console.log(obj1.b.c); // 输出 2，原对象未被修改
  注意：这种方法不能处理函数、undefined、Symbol等特殊类型，也不能处理循环引用的对象。

  2. 自定义递归深拷贝函数：
  function deepClone(obj) {
        if (obj === null || typeof obj !== 'object') {
            return obj; // 基本数据类型直接返回
        }
        if (Array.isArray(obj)) {
            const arrCopy = [];
            for (let item of obj) {
                arrCopy.push(deepClone(item)); // 递归拷贝数组元素
            }
            return arrCopy;
        }
        const objCopy = {};
        for (let key in obj) {
            if (obj.hasOwnProperty(key)) {
                objCopy[key] = deepClone(obj[key]); // 递归拷贝对象属性
            }
        }
        return objCopy;
    }

    const obj1 = { a: 1, b: { c: 2 } };
    const deepCopy = deepClone(obj1);
    deepCopy.b.c = 3; // 修改深拷贝的对象
    console.log(obj1.b.c); // 输出 2，原对象未被修改
  总结
  - 浅拷贝：适用于简单的对象复制，但对于嵌套对象的修改会影响原对象。
  - 深拷贝：适用于需要完全独立副本的场景，确保修改新对象不会影响原对象。
  -->
</head>

<body>

  <script>
    // 需求: 判断一个标识符是否是对象类型
    function isObject(value) {
      // null,object,function,array
      // null -> object
      // function -> function -> true
      // object/array -> object -> true
      const valueType = typeof value
      return (value !== null) && (valueType === 'object' || valueType === 'function')
    }

    // const name = "string"
    // const age = 18
    // const foo = {}
    // const bar = function () { }
    // const arr = []

    // console.log(isObject(null)) // false
    // console.log(isObject(bar)) // true
    // console.log(isObject(name)) // false
    // console.log(isObject(foo)) // true
    // console.log(isObject(arr)) // true
  </script>
  <script>

    function deepClone(origin) {
      if (!isObject(origin)) return origin

      const newObj = {}
      for (const key in origin) {
        newObj[key] = deepClone(origin[key])
      }
      return newObj
    }

    const obj = {
      name: "deepClone",
      age: 18,
      address: {
        city: "北京",
        home: {
          name: "home"
        }
      },
      arr: [1, 2, 3]
    }

    const newObj = deepClone(obj)
    obj.address.home.name = "deep-home1"
    console.log(newObj.address.home.name, newObj);
    
    
  </script>

</body>

</html>